查看原文
其他

开发者说丨ROS理论与实践①:ROS概述与环境搭建

赵虚左 Apollo开发者社区 2022-07-29


学习是一个循序渐进的过程,具体到计算机领域的软件开发层面,每当接触一个新的知识模块时,按照一般的步骤,我们会先去了解该模块的相关概念,然后再安装官方推荐的软件包,接下来再搭建其集成的开发环境。准备工作完毕之后,才算是叩开了新领域的大门。学习ROS,我们也是遵循这一流程,本章作为ROS体系的开篇主要会介绍:


  • ROS的相关概念。

  • 怎样安装ROS。

  • 如何搭建ROS的集成开发环境。


该章内容学习完毕预期达成的目标如下:


  • 了解ROS概念,设计目标以及发展历程。

  • 能够独立安装并运行ROS。

  • 能够使用C++和Python分别实现ROS版本的HelloWorld。

  • 能够搭建ROS的集成开发环境。

  • 了解ROS架构设计。


案例演示,ROS安装成功后,运行内置案例:通过键盘控制乌龟运动。



下面是由社区开发者—赵虚左提供的文章,对ROS概述与环境搭建进行详细讲解,希望这篇文章能给感兴趣的开发者带来更多帮助。



  ENJOY THE FOLLOWING  





机器人是一种高度复杂且庞大的系统性实现,机器人设计包含了机械加工、机械结构设计、硬件设计、嵌入式软件设计、上层软件设计....各种硬件与软件实现,甚至可以说机器人系统是当今工业体系的集大成者,其复杂度之高,也说明了机器人研发之艰辛。不过在机器人研发中,虽然机器人的构成复杂,但是宏观上其组成都是高度类似的,不同的公司、组织或个人在研发过程中,都会涉及到一些通用的实现,尤其是后期随着机器人硬件越来越丰富,软件代码的复用性和模块化开发需求也是愈发强烈,秉着不重复发明轮子的原则,业内也亟需一套机器人通用软件框架来提升功能模块的复用性,在此大背景下,于2007年,一家名为 柳树车库(Willow Garage)的机器人公司发布了ROS(机器人操作系统),并且随着该系统的不断迭代与完善,如今ROS已经成为机器人领域的事实标准。



ROS全称Robot Operating System(机器人操作系统)


  • ROS是适用于机器人的开源元操作系统。

  • ROS集成了大量的工具、库、协议,简化对机器人的控制。

  • 还提供了用于在多台计算机上获取、构建、编写以及运行代码的工具和库,ROS在某些方面类似于“机器人框架”。

  • ROS设计者将ROS表述为“ROS = Plumbing + Tools + Capabilities + Ecosystem”,即ROS是通讯机制、工具软件包、机器人高层技能以及机器人生态系统的集合体。



创建真正强大的通用机器人软件很难。从机器人的角度来看,在人类看来微不足道的问题通常在任务实例和环境实例之间千差万别。处理这些变化是如此困难,以至没有任何一个个人,实验室或机构可以希望自己做。


因此,ROS是从头开始构建的,以鼓励协作机器人软件的开发。例如,一个实验室可能拥有室内环境地图绘制方面的专家,并且可以为创建地图提供世界一流的系统。另一个小组可能有专家使用地图进行导航,而另一个小组可能已经发现了一种计算机视觉方法,可以很好地识别杂乱的小物体。ROS是专门为此类团体设计的,它们可以相互协作并以彼此的工作为基础。


  • 代码复用:ROS的目标不是成为具有最多功能的框架,ROS的主要目标是支持机器人技术研发中的代码重用。

  • 分布式:ROS是进程(也称为Nodes)的分布式框架,ROS中的进程可分布于不同主机,不同主机协同工作,从而分散计算压力。

  • 松耦合:ROS中功能模块封装于独立的功能包或元功能包,便于分享,功能包内的模块以节点为单位运行,以ROS标准的IO作为接口,开发者不需要关注模块内部实现,只要了解接口规则就能实现复用,实现了模块间点对点的松耦合连接。


为了支持共享和协作这一主要目标,ROS框架还有其他一些目标:


  • 精简:ROS被设计为尽可能精简,以便为ROS编写的代码可以与其他机器人软件框架一起使用。ROS易于与其他机器人软件框架集成:ROS已与OpenRAVE、Orocos和Player集成。

  • 语言独立性:包括Java、C++、Python等。为了支持更多应用开发和移植,ROS设计为一种语言弱相关的框架结构,使用简洁,中立的定义语言描述模块间的消息接口,在编译中再产生所使用语言的目标文件,为消息交互提供支持,同时允许消息接口的嵌套使用。

  • 易于测试:ROS具有称为rostest的内置单元/集成测试框架,可轻松安装和拆卸测试工具。

  • ROS适用于大型运行时系统和大型开发流程。

  • 组件化工具包丰富:ROS可采用组件化方式集成一些工具和软件到系统中并作为一个组件直接使用,如RVIZ(3D可视化工具),开发者根据ROS定义的接口在其中显示机器人模型等,组件还包括仿真环境和消息查看工具等。

  • 免费且开源:开发者众多,功能包多。


  • ROS是一个由来已久、贡献者众多的大型软件项目。在ROS诞生之前,很多学者认为,机器人研究需要一个开放式的协作框架,并且已经有不少类似的项目致力于实现这样的框架。在这些工作中,斯坦福大学在2000年年中开展了一系列相关研究项目,如斯坦福人工智能机器人(STandford AI Robot, STAIR)项目、个人机器人(Personal Robots, PR)项目等,在上述项目中,在研究具有代表性、集成式人工智能系统的过程中,创立了用于室内场景的高灵活性、动态软件系统,其可以用于机器人学研究。

  • 2007年,柳树车库(Willow Garage)提供了大量资源,用于将斯坦福大学机器人项目中的软件系统进行扩展与完善,同时,在无数研究人员的共同努力下,ROS的核心思想和基本软件包逐渐得到完善。

  • ROS的发行版本(ROS distribution)指ROS软件包的版本,其与Linux的发行版本(如Ubuntu)的概念类似。推出ROS发行版本的目的在于使开发人员可以使用相对稳定的代码库,直到其准备好将所有内容进行版本升级为止。因此,每个发行版本推出后,ROS开发者通常仅对这一版本的bug进行修复,同时提供少量针对核心软件包的改进。

  • 版本特点:按照英文字母顺序命名,ROS目前已经发布了ROS1的终极版本:noetic,并建议后期过渡至ROS2版本。noetic版本之前默认使用的是 Python2,noetic 支持 Python3。

    建议版本:noetic 或 melodic 或 kinetic。

另请参考:https://www.ros.org/about-ros/

另请参考:http://wiki.ros.org/ROS/Introduction

另请参考:http://wiki.ros.org/Distributions





我们使用的是ROS版本是Noetic,那么可以在ubuntu20.04、Mac或 windows10系统上安装,虽然一般用户平时使用的操作系统以windows居多,但是ROS之前的版本基本都不支持windows,所以当前我们选用的操作系统是 ubuntu,以方便向历史版本过渡。ubuntu安装常用方式有两种:


  • 实体机安装ubuntu(较为常用的是使用双系统,windows 与 ubuntu 并存)。

  • 虚拟机安装ubuntu。


两种方式比较,各有优缺点:


  • 方案1可以保证性能,且不需要考虑硬件兼容性问题,但是和windows系统交互不便。

  • 方案2可以方便的实现windows与ubuntu交互,不过性能稍差,且与硬件交互不便。


在ROS中,一些仿真操作是比较耗费系统资源的,且经常需要和一些硬件(雷达、摄像头、arduino....)交互,因此,原则上建议采用方案1,不过如果只是出于学习目的,那么方案2也基本受用,本教程在此选用的是方案2。当然,具体采用哪种实现方案,请按需选择。


如果采用虚拟机安装ubuntu,再安装ROS的话,大致流程如下:


  1. 安装虚拟机软件(比如:virtualbox 或 VMware)。

  2. 使用虚拟机软件虚拟一台主机。

  3. 在虚拟主机上安装ubuntu 20.04。

  4. 在ubuntu上安装ROS。

  5. 测试ROS环境是否可以正常运行。


虚拟机软件选择上,对于我们学习而言virtualbox和VMware都可以满足需求,二者比较,前者免费,后者收费,所以本教程选用virtualbox。


1. 下载virtualbox


安装virtualbox需要先访问官网,下载安装包,官网下载地址:https://www.virtualbox.org/wiki/Downloads



2. 安装virtualbox


virtualbox安装比较简单,如果没有特殊需求,双击安装文件,一直 "下一步" 即可。






安装完毕后,虚拟机已经可以正常启动了,接下来需要使用其虚拟出一台计算机。


使用virtual虚拟计算机的过程也不算复杂,只需要按照提示配置其相关参数即可。



1. ubuntu安装


首先下载Ubuntu的镜像文件,链接如下:http://mirrors.aliyun.com/ubuntu-releases/20.04/


配置虚拟主机。关联Ubuntu镜像文件:



启动后,开始配置ubuntu操作系统。



安装过程中,断开网络连接,可以提升安装速度。



安装完毕后,会给出重启提示,点击重启确定按钮即可。



到目前为止VirtualBox已经正常安装了ubuntu,并启动成功。


2. 使用优化


为了优化ubuntu操作的用户体验,方便虚拟机与宿主机的文件交换以及USB设备的正常使用,还需做如下操作:


1. 启动文件交换模式


2. 安装虚拟机工具



重启使之生效,选择菜单栏的自动调整窗口大小,然后ubuntu桌面会自动使用窗口大小:ctrl + F全屏。


3. 安装扩展插件


先去virtualbox官网下载扩展包。



在virtual box中添加扩展工具。



在虚拟机中添加USB设备。



重启后,使用ll /dev/ttyUSB*或 ll /dev/ttyACM*即可查看新接入的设备。


4. 其他


其他设置,比如输入法可以根据喜好自行下载安装。


ubuntu 20.04鼠标右击没有创建文件选项,如果想要设置此选项,可以进入主目录下的模板目录,使用gedit创建一个空文本文档,以后,鼠标右击就可以添加新建文档选项,并且创建的文档与当前自定义的文档名称一致。


Ubuntu安装完毕后,就可以安装ROS操作系统了,具体流程可以参考ROS wiki官网演示:http://wiki.ros.org/kinetic/Installation/Ubuntu


1. 配置ubuntu的软件和更


配置ubuntu的软件和更新,允许安装不经认证的软件。


首先打开“软件和更新”对话框,具体可以在Ubuntu搜索按钮中搜索。


打开后按照下图进行配置(确保你的"restricted", "universe," 和 "multiverse."前是打上勾的)。



2. 设置安装源


官方默认安装源:


sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'

<左右滑动以查看完整代码>


或来自国内中科大的安装源:


sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'

<左右滑动以查看完整代码>


或来自国内清华的安装源:


sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'

<左右滑动以查看完整代码>


PS:回车后,可能需要输入管理员密码。


3. 设置key


sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

<左右滑动以查看完整代码>


4. 安装


首先需要更新 apt(以前是 apt-get, 官方建议使用 apt 而非 apt-get),apt 是用于从互联网仓库搜索、安装、升级、卸载软件或操作系统的工具。


sudo apt update

<左右滑动以查看完整代码>


等待...


然后,再安装所需类型的ROS,ROS多个类型:Desktop-Full、Desktop、ROS-Base。这里介绍较为常用的Desktop-Full(官方推荐)安装:ROS、 rqt、rviz、 robot-generic libraries、2D/3D simulators、 navigation and 2D/3D perception。


等待...(比较耗时)


友情提示: 由于网络原因,导致连接超时,可能会安装失败,如下所示:



可以多次重复调用更新和安装命令,直至成功。


5. 环境设置


配置环境变量,方便在任意终端中使用ROS。


1echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
2source ~/.bashrc

<左右滑动以查看完整代码>


6. 卸载


如果需要卸载ROS可以调用如下命令:


sudo apt-get remove ros-noetic-*

<左右滑动以查看完整代码>


注意:在ROS版本noetic中无需构建软件包的依赖关系,没有rosdep的相关安装与配置。


ROS内置了一些小程序,可以通过运行这些小程序以检测 ROS 环境是否可以正常运行。


  1. 首先启动三个命令行(ctrl + alt + T)。

  2. 命令行1键入:roscore。

  3. 命令行2键入:rosrun turtlesim turtlesim_node(此时会弹出图形化界面)。

  4. 命令行3键入:rosrun turtlesim turtle_teleop_key(在3中可以通过上下左右控制2中乌龟的运动)。


最终结果如下所示:






编写ROS程序,在控制台输出文本: Hello World,分别使用C++和Python实现。


1. 创建工作空间以及src目录并初始化


1mkdir -p 自定义空间名称/src
2cd 自定义空间名称/src
3catkin_make

<左右滑动以查看完整代码>




生成CMakeList.txt。


2. 进入src创建ros包并添加依赖


1cd src
2catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs

<左右滑动以查看完整代码>

生成包以及包下附属文件: CMakeList.txt package.xml src .....


3. 进入ros包的src目录编辑源文件

cd 自定义空的包

<左右滑动以查看完整代码>


C++源码实现(文件名自定义)


1#include "ros/ros.h"
2
3int main(int argc, char *argv[])
4
{
5//执行 ros 节点初始化
6ros::init(argc,argv,"hello");
7//创建 ros 节点句柄(非必须)
8ros::NodeHandle n;
9//控制台输出 hello world
10ROS_INFO("hello world!");
11
12return 0;
13}

<左右滑动以查看完整代码>


4. 编辑ros包下的Cmakelist.txt文件


1add_executable(步骤3的源文件名
2src/步骤3的源文件名.cpp
3)
4target_link_libraries(步骤3的源文件名
5${catkin_LIBRARIES}
6)

<左右滑动以查看完整代码>


5. 进入工作空间目录并编译


1cd 自定义空间名称
2catkin_make

<左右滑动以查看完整代码>


生成 build devel ....


6. 执行


先启动命令行1:


roscore

<左右滑动以查看完整代码>

再启动命令行2:


1cd 工作空间
2source ./devel/setup.bash
3rosrun 包名 C++节点

<左右滑动以查看完整代码>

命令行输出:HelloWorld!


PS:source ~/工作空间/devel/setup.bash可以添加进.bashrc文件,使用上更方便。


添加方式1:直接使用gedit 或 vi编辑 .bashrc文件,最后添加该内容


添加方式2:echo "source ~/工作空间/devel/setup.bash" >> ~/.bashrc。


ROS的python实现与C++实现步骤类似,步骤1和步骤2完全一致,也可以上接前面案例,在之前的工作空间的功能包中添加python实现。


1. 进入ros包添加scripts目录并编辑python文件


1cd ros包
2mkdir scripts

<左右滑动以查看完整代码>


新建python文件:(文件名自定义)


1 #! /usr/bin/env python
2
3"""
4Python 版 HelloWorld
5
6"""

7import rospy
8
9if __name__ == "__main__":
10rospy.init_node("Hello")
11rospy.loginfo("Hello World!!!!")

<左右滑动以查看完整代码>


2. 为python文件添加可执行权限

chmod +d 自定义文件名.py

<左右滑动以查看完整代码>

3. 编辑ros包下的CamkeList.txt文件


1 catkin_install_python(PROGRAMS scripts/自定义文件名.py
2 DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
3 )

<左右滑动以查看完整代码>


4. 进入工作空间目录并执行(无需编译)


先保证roscore启动


1cd 工作空间
2source ./devel/setup.bash
3rosrun 包名 自定义文件名.py

<左右滑动以查看完整代码>

输出结果:Hello World!!!!。





和大多数开发环境一样,理论上,在ROS中,只需要记事本就可以编写基本的ROS程序,但是工欲善其事必先利其器,为了提高开发效率,可以先安装集成开发工具和使用方便的工具:终端、IDE。


在ROS中,需要频繁的使用到终端,推荐一款较为好用的终端:Terminator


1. 安装


sudo apt install terminator

<左右滑动以查看完整代码>

2. 添加到收藏夹


显示应用程序 ---> 搜索 terminator ---> 右击 选择 添加到收藏夹。


3. Terminator常用快捷键


第一部份:关于在同一个标签内的操作。


1Alt+Up                          //移动到上面的终端
2Alt+Down                        //移动到下面的终端
3Alt+Left                        //移动到左边的终端
4Alt+Right                       //移动到右边的终端
5Ctrl+Shift+O                    //水平分割终端
6Ctrl+Shift+E                    //垂直分割终端
7Ctrl+Shift+Right                //在垂直分割的终端中将分割条向右移动
8Ctrl+Shift+Left                 //在垂直分割的终端中将分割条向左移动
9Ctrl+Shift+Up                   //在水平分割的终端中将分割条向上移动
10Ctrl+Shift+Down                 //在水平分割的终端中将分割条向下移动
11Ctrl+Shift+S                    //隐藏/显示滚动条
12Ctrl+Shift+F                    //搜索
13Ctrl+Shift+C                    //复制选中的内容到剪贴板
14Ctrl+Shift+V                    //粘贴剪贴板的内容到此处
15Ctrl+Shift+W                    //关闭当前终端
16Ctrl+Shift+Q                    //退出当前窗口,当前窗口的所有终端都将被关闭
17Ctrl+Shift+X                    //最大化显示当前终端
18Ctrl+Shift+Z                    //最大化显示当前终端并使字体放大
19Ctrl+Shift+N or Ctrl+Tab        //移动到下一个终端
20Ctrl+Shift+P or Ctrl+Shift+Tab  //Crtl+Shift+Tab 移动到之前的一个终端

<左右滑动以查看完整代码>

第二部份:有关各个标签之间的操作。


1F11                             //全屏开关
2Ctrl+Shift+T                    //打开一个新的标签
3Ctrl+PageDown                   //移动到下一个标签
4Ctrl+PageUp                     //移动到上一个标签
5Ctrl+Shift+PageDown             //将当前标签与其后一个标签交换位置
6Ctrl+Shift+PageUp               //将当前标签与其前一个标签交换位置
7Ctrl+Plus (+)                   //增大字体
8Ctrl+Minus (-)                  //减小字体
9Ctrl+Zero (0)                   //恢复字体到原始大小
10Ctrl+Shift+R                    //重置终端状态
11Ctrl+Shift+G                    //重置终端状态并clear屏幕
12Super+g                         //绑定所有的终端,以便向一个输  入能够输入到所有的终端
13Super+Shift+G                   //解除绑定
14Super+t                         //绑定当前标签的所有终端,向一个终端输入的内容会自动输入到其他终端
15Super+Shift+T                   //解除绑定
16Ctrl+Shift+I                    //打开一个窗口,新窗口与原来的窗口使用同一个进程
17Super+i                         //打开一个新窗口,新窗口与原来的窗口使用不同的进程

<左右滑动以查看完整代码>

1. 下载


vscode下载:

https://code.visualstudio.com/docs?start=true


2. vscode安装与卸载


1. 安装


方式1:双击安装即可(或右击选择安装)


方式2:sudo dpkg -i xxxx.deb


2. 卸载


sudo dpkg --purge code

<左右滑动以查看完整代码>


3. vscode集成ROS插件


使用VScode开发ROS程序,需要先安装一些插件,常用插件如下:


4. vscode使用_基本配置


1. 创建ROS工作空间


1mkdir -p xxx_ws/src(必须得有 src)
2cd xxx_ws
3catkin_make

<左右滑动以查看完整代码>


2. 启动vscode


进入 xxx_ws 启动 vscode


1cd xxx_ws
2code .

<左右滑动以查看完整代码>


3. vscode中编译ros


快捷键ctrl + shift+B调用编译,选择:catkin_make:build。


可以点击配置设置为默认,修改.vscode/tasks.json文件。


1{
2// 有关 tasks.json 格式的文档,请参见
3// https://go.microsoft.com/fwlink/?LinkId=733558
4"version""2.0.0",
5"tasks": [
6    {
7        "label""catkin_make:debug"//代表提示的描述性信息
8        "type""shell",  //可以选择shell或者process,如果是shell代码是在shell里面运行一个命令,如果是process代表作为一个进程来运行
9        "command""catkin_make",//这个是我们需要运行的命令
10        "args": [],//如果需要在命令后面加一些后缀,可以写在这里,比如-DCATKIN_WHITELIST_PACKAGES=“pac1;pac2”
11        "group": {"kind":"build","isDefault":true},
12        "presentation": {
13            "reveal""always"//可选always或者silence,代表是否输出信息
14        },
15        "problemMatcher""$msCompile"
16    }
17]
18}

<左右滑动以查看完整代码>


4. 创建ROS功能包


选定src右击 ---> create catkin package


设置包名,添加依赖。


5. C++ 实现


在功能包的src下新建cpp文件。


1/*
2控制台输出 HelloVSCode !!!
3
4*/

5#include "ros/ros.h"
6
7int main(int argc, char *argv[])
8
{
9setlocale(LC_ALL,"");
10//执行节点初始化
11ros::init(argc,argv,"HelloVSCode");
12
13//输出日志
14ROS_INFO("Hello VSCode!!!哈哈哈哈哈哈哈哈哈哈");
15return 0;
16}

<左右滑动以查看完整代码>


PS1:如果没有代码提示


修改 .vscode/c_cpp_properties.json


设置 "cppStandard": "c++17"


PS2: main函数的参数不可以被const修饰。


PS3:当ROS__INFO终端输出有中文时,会出现乱码。


INFO: ????????????????????????


解决办法:在函数开头加入下面代码的任意一句。


1setlocale(LC_CTYPE, "zh_CN.utf8");
2setlocale(LC_ALL, "");

<左右滑动以查看完整代码>


6. python实现


在功能包下新建scripts文件夹,添加python文件,并添加可执行权限。


1#! /usr/bin/env python
2"""
3Python 版本的 HelloVScode,执行在控制台输出 HelloVScode
4实现:
51.导包
62.初始化 ROS 节点
73.日志输出 HelloWorld
8
9
10"""

11
12import rospy # 1.导包
13
14if __name__ == "__main__":
15
16rospy.init_node("Hello_Vscode_p")  # 2.初始化 ROS 节点
17rospy.loginfo("Hello VScode, 我是 Python ....")  #3.日志输出 HelloWorld

<左右滑动以查看完整代码>

PS:


(1) 第一行解释器声明,可以使用绝对路径定位到python3的安装路径#! /usr/bin/python3,但是不建议。


(2) 建议使用#!/usr/bin/env python但是会抛出异常:/usr/bin/env: “python”,没有那个文件或目录。


(3) 解决1: #!/usr/bin/env python3直接使用python3,但存在问题:不兼容之前的ROS相关python实现。


(4) 解决2:创建一个链接符号到python命令:

sudo ln -s /usr/bin/python3 /usr/bin/python。


7. 配置CMakeLists.txt


C++ 配置:


1add_executable(节点名称
2src/C++源文件名.cpp
3)
4target_link_libraries(节点名称
5${catkin_LIBRARIES}
6)

<左右滑动以查看完整代码>

Python配置:


1catkin_install_python(PROGRAMS scripts/自定义文件名.py
2DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
3)

<左右滑动以查看完整代码>


8. 编译执行


编译: ctrl+shift+B。


执行:和之前一致,只是可以在VScode中添加终端,首先执行:source ./devel/setup.bash


5. 其他IDE


ROS开发可以使用的IDE还是比较多的,除了上述的VScode,还有Eclipse、QT、PyCharm、Roboware等,详情可以参考官网介绍:

http://wiki.ros.org/IDEs


QT Creator Plugin for ROS,参考教程:

https://ros-qtc-plugin.readthedocs.io/en/latest/


Roboware参考:

http://www.roboware.me/#/


1. 需求


需求:一个程序中可能需要启动多个节点,比如:ROS 内置的小乌龟案例,如果要控制乌龟运动,要启动多个窗口,分别启动 roscore、乌龟界面节点、键盘控制节点。如果每次都调用 rosrun 逐一启动,显然效率低下,如何优化?

方案:官方给出的优化策略是使用 launch 文件,可以一次性启动多个 ROS 节点。


2. 实现


1. 选定功能包右击 --->添加launch文件夹。

2. 选定launch文件夹右击 --->添加launch文件。

3. 编辑launch文件内容。


1<launch>
2<node pkg="helloworld" type="demo_hello" name="hello" output="screen" />
3<node pkg="turtlesim" type="turtlesim_node" name="t1"/>
4<node pkg="turtlesim" type="turtle_teleop_key" name="key1" />
5launch>

<左右滑动以查看完整代码>

    • node --->包含的某个节点

    • pkg ----->功能包

    • type ---->被运行的节点文件

    • name -->为节点命名

    • output->设置日志的输出目标


    4. 运行launch文件

    roslaunch包名launch文件名


    5. 运行结果:一次性启动了多个节点。





    到目前为止,我们已经安装了ROS,运行了ROS中内置的小乌龟案例,并且也编写了ROS小程序,对ROS也有了一个大概的认知,当然这个认知可能还是比较模糊并不清晰的,接下来,我们要从宏观上来介绍一下ROS的架构设计。立足不同的角度,对ROS架构的描述也是不同的,一般我们可以从设计者、维护者、系统结构与自身结构4个角度来描述ROS结构:


    1. 设计者


    ROS设计者将ROS表述为“ROS = Plumbing + Tools + Capabilities + Ecosystem”。


    • Plumbing:通讯机制(实现ROS不同节点之间的交互)。

    • Tools :工具软件包(ROS中的开发和调试工具)

    • Capabilities:机器人高层技能(ROS中某些功能的集合,比如:导航)。

    • Ecosystem:机器人生态系统(跨地域、跨软件与硬件的ROS联盟)。


    2. 维护者


    立足维护者的角度:ROS架构可划分为两大部分。


    • main:核心部分,主要由Willow Garage和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的核心部分的程序编写。

    • universe:全球范围的代码,有不同国家的ROS社区组织开发和维护。一种是库的代码,如OpenCV、PCL等;库的上一层是从功能角度提供的代码,如人脸识别,他们调用下层的库;最上层的代码是应用级的代码,让机器人完成某一确定的功能。


    3. 系统架构


    立足系统架构:ROS 可以划分为三层。


    • OS层,也即经典意义的操作系统ROS只是元操作系统,需要依托真正意义的操作系统,目前兼容性最好的是Linux的Ubuntu,Mac、Windows也支持ROS的较新版本。

    • 中间层,是ROS封装的关于机器人开发的中间件,比如:基于 TCP/UDP继续封装的TCPROS/UDPROS通信系统,用于进程间通信Nodelet,为数据的实时性传输提供支持。另外,还提供了大量的机器人开发实现库,如:数据类型定义、坐标变换、运动控制等。

    • 应用层,功能包,以及功能包内的节点,比如: master turtlesim的控制与运动节点等。


    4. 自身结构


    就ROS自身实现而言:也可以划分为三层。


    • 文件系统,ROS文件系统级指的是在硬盘上面查看的ROS源代码的组织形式

    • 计算图,ROS分布式系统中不同进程需要进行数据交互,计算图可以以点对点的网络形式表现数据交互过程,计算图中的重要概念:节点(Node)、消息(message)、通信机制_主题(topic)、通信机制_服务(service)。

    • 开源社区,ROS的社区级概念是ROS网络上进行代码发布的一种表现形式。

      发行版(Distribution)ROS发行版是可以独立安装、带有版本号的一系列综合功能包。ROS发行版像Linux发行版一样发挥类似的作用。这使得ROS软件安装更加容易,而且能够通过一个软件集合维持一致的版本。

      ○ 软件库(Repository)ROS依赖于共享开源代码与软件库的网站或主机服务,在这里不同的机构能够发布和分享各自的机器人软件与程序。

      ○ ROS维基(ROS Wiki)ROS Wiki是用于记录有关ROS系统信息的主要论坛。任何人都可以注册账户、贡献自己的文件、提供更正或更新、编写教程以及其他行为。

      ○ Bug提交系统(Bug Ticket System)如果你发现问题或者想提出一个新功能,ROS提供这个资源去做这些。

      ○ 邮件列表(Mailing list)ROS用户邮件列表是关于ROS的主要交流渠道,能够像论坛一样交流从ROS软件更新到ROS软件使用中的各种疑问或信息。

      ○ ROS问答(ROS Answer)用户可以使用这个资源去提问题。

      ○ 博客(Blog)你可以看到定期更新、照片和新闻,网址是http://www.ros.org/news

    现在处于学习的初级阶段,只是运行了ROS的内置案例,编写了简单的ROS实现,因此,受限于当前进度,不会详细介绍所有设计架构中的所有模块,当前只介绍文件系统与计算图,下一章会介绍ROS的通信机制,这也是ROS的核心实现之一。


    ROS文件系统级指的是在硬盘上面查看的ROS源代码的组织形式。

    1WorkSpace --- 自定义的工作空间
    2
    3|--- build:缓存中间文件,msg、srv、action、dynamic_reconfigure ... 的编译后的中间文件
    4
    5|--- devel: 目标文件, 执行节点前,先调用 source ./devel/setup.xxxsh 将工作空间刷新到 PATH 环境变量
    6
    7|--- src: 源码
    8
    9    |-- package:功能包(ROS基本单元)包含多个节点、库与配置文件,包名所有字母小写,只能由字母、数字与下划线组成
    10
    11        |-- CMakeLists.txt 配置编译规则,比如源文件、依赖项、目标文件
    12
    13        |-- package.xml 包信息,比如:包名、版本、作者、依赖项...(以前版本是 manifest.xml)
    14
    15        |-- scripts 存储python文件
    16
    17        |-- src 存储C++文件
    18
    19        |-- include 头文件
    20
    21        |-- msg 消息通信格式文件
    22
    23        |-- srv 服务通信格式文件
    24
    25        |-- action 动作格式文件
    26
    27        |-- launch 可一次性运行多个节点
    28
    29        |-- config 配置信息
    30
    31    |-- CMakeLists.txt: 编译的基本配置

    <左右滑动以查看完整代码>


    ROS 文件系统中部分目录和文件前面编程中已经有所涉及,比如功能包的创建、src目录下cpp文件的编写、scripts目录下python文件的编写、launch目录下launch文件的编写,并且也配置了 package.xml 与 CMakeLists.txt 文件。其他目录下的内容后面教程将会再行介绍,当前我们主要介绍: package.xml 与 CMakeLists.txt 这两个配置文件。


    1. package.xml


    该文件定义有关软件包的属性,例如软件包名称、版本号、作者、维护者以及对其他catkin软件包的依赖性。请注意,该概念类似于旧版rosbuild 构建系统中使用的manifest.xml文件。


    1<?xml version="1.0"?>
    2<!-- 格式: 以前是 1,推荐使用格式 2 -->
    3<package format="2">
    4<!-- 包名 -->
    5<name>demo01_hello_vscode</name>
    6<!-- 版本 -->
    7<version>0.0.0</version>
    8<!-- 描述信息 -->
    9<description>The demo01_hello_vscode package</description>
    10
    11<!-- One maintainer tag required, multiple allowed, one person per tag -->
    12<!-- Example:  -->
    13<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
    14<!-- 维护人员 -->
    15<maintainer email="xuzuo@todo.todo">xuzuo</maintainer>
    16
    17
    18<!-- One license tag required, multiple allowed, one license per tag -->
    19<!-- Commonly used license strings: -->
    20<!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
    21<!-- 许可证信息,ROS核心组件默认 BSD -->
    22<license>TODO</license>
    23
    24
    25<!-- Url tags are optional, but multiple are allowed, one per tag -->
    26<!-- Optional attribute type can be: website, bugtracker, or repository -->
    27<!-- Example: -->
    28<!-- <url type="website">http://wiki.ros.org/demo01_hello_vscode</url> -->
    29
    30
    31<!-- Author tags are optional, multiple are allowed, one per tag -->
    32<!-- Authors do not have to be maintainers, but could be -->
    33<!-- Example: -->
    34<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
    35
    36
    37<!-- The *depend tags are used to specify dependencies -->
    38<!-- Dependencies can be catkin packages or system dependencies -->
    39<!-- Examples: -->
    40<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
    41<!--   <depend>roscpp</depend> -->
    42<!--   Note that this is equivalent to the following: -->
    43<!--   <build_depend>roscpp</build_depend> -->
    44<!--   <exec_depend>roscpp</exec_depend> -->
    45<!-- Use build_depend for packages you need at compile time: -->
    46<!--   <build_depend>message_generation</build_depend> -->
    47<!-- Use build_export_depend for packages you need in order to build against this package: -->
    48<!--    <build_export_depend>message_generation</build_export_depend> -->
    49<!-- Use buildtool_depend for build tool packages: -->
    50<!--   <buildtool_depend>catkin</buildtool_depend> -->
    51<!-- Use exec_depend for packages you need at runtime: -->
    52<!--   <exec_depend>message_runtime</exec_depend> -->
    53<!-- Use test_depend for packages you need only for testing: -->
    54<!--   <test_depend>gtest</test_depend> -->
    55<!-- Use doc_depend for packages you need only for building documentation: -->
    56<!--   <doc_depend>doxygen</doc_depend> -->
    57<!-- 依赖的构建工具,这是必须的 -->
    58<buildtool_depend>catkin</buildtool_depend>
    59
    60<!-- 指定构建此软件包所需的软件包 -->
    61<build_depend>roscpp</build_depend>
    62<build_depend>rospy</build_depend>
    63<build_depend>std_msgs</build_depend>
    64
    65<!-- 指定根据这个包构建库所需要的包 -->
    66<build_export_depend>roscpp</build_export_depend>
    67<build_export_depend>rospy</build_export_depend>
    68<build_export_depend>std_msgs</build_export_depend>
    69
    70<!-- 运行该程序包中的代码所需的程序包 -->  
    71<exec_depend>roscpp</exec_depend>
    72<exec_depend>rospy</exec_depend>
    73<exec_depend>std_msgs</exec_depend>
    74
    75
    76<!-- The export tag contains other, unspecified, tags -->
    77<export>
    78<!-- Other tools can request additional information be placed here -->
    79
    80</export>
    81</package>

    <左右滑动以查看完整代码>


    2. CMakelists.txt


    文件CMakeLists.txt是CMake构建系统的输入,用于构建软件包。任何兼容CMake的软件包都包含一个或多个CMakeLists.txt文件,这些文件描述了如何构建代码以及将代码安装到何处。


    1cmake_minimum_required(VERSION 3.0.2) #所需 cmake 版本
    2project(demo01_hello_vscode) #包名称,会被   ${PROJECT_NAME} 的方式调用
    3
    4#
    # Compile as C++11, supported in ROS Kinetic and newer
    5# add_compile_options(-std=c++11)
    6
    7#
    # Find catkin macros and libraries
    8## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    9## is used, also find other catkin packages
    10#设置构建所需要的软件包
    11find_package(catkin REQUIRED COMPONENTS
    12roscpp
    13rospy
    14std_msgs
    15)
    16
    17 #
    # System dependencies are found with CMake's  conventions
    18#默认添加系统依赖
    19# find_package(Boost REQUIRED COMPONENTS system)
    20
    21
    22#
    # Uncomment this if the package has a setup.py. This macro ensures
    23## modules and global scripts declared therein get installed
    24## See http://ros.org/doc/api/catkin/html/user_guide /setup_dot_py.html
    25# 启动 python 模块支持
    26# catkin_python_setup()
    27
    28#
    ###############################################
    29## Declare ROS messages, services and actions ##
    30## 声明 ROS 消息、服务、动作... ##
    31################################################
    32
    33#
    # To declare and build messages, services or actions from within this
    34## package, follow these steps:
    35## * Let MSG_DEP_SET be the set of packages whose message types you use in
    36##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
    37## * In the file package.xml:
    38##   * add a build_depend tag for "message_generation"
    39##   * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
    40##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
    41##     but can be declared for certainty nonetheless:
    42##     * add a exec_depend tag for "message_runtime"
    43## * In this file (CMakeLists.txt):
    44##   * add "message_generation" and every package in MSG_DEP_SET to
    45##     find_package(catkin REQUIRED COMPONENTS ...)
    46##   * add "message_runtime" and every package in MSG_DEP_SET to
    47##     catkin_package(CATKIN_DEPENDS ...)
    48##   * uncomment the add_*_files sections below as needed
    49##     and list every .msg/.srv/.action file to be processed
    50##   * uncomment the generate_messages entry below
    51##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
    52
    53#
    # Generate messages in the 'msg' folder
    54# add_message_files(
    55#   FILES
    56#   Message1.msg
    57#   Message2.msg
    58# )
    59
    60#
    # Generate services in the 'srv' folder
    61# add_service_files(
    62#   FILES
    63#   Service1.srv
    64#   Service2.srv
    65# )
    66
    67#
    # Generate actions in the 'action' folder
    68# add_action_files(
    69#   FILES
    70#   Action1.action
    71#   Action2.action
    72# )
    73
    74#
    # Generate added messages and services with any   dependencies listed here
    75# 生成消息、服务时的依赖包
    76# generate_messages(
    77#   DEPENDENCIES
    78#   std_msgs
    79# )
    80
    81#
    ###############################################
    82## Declare ROS dynamic reconfigure parameters ##
    83## 声明 ROS 动态参数配置 ##
    84################################################
    85
    86#
    # To declare and build dynamic reconfigure parameters  within this
    87## package, follow these steps:
    88## * In the file package.xml:
    89##   * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
    90## * In this file (CMakeLists.txt):
    91##   * add "dynamic_reconfigure" to
    92##     find_package(catkin REQUIRED COMPONENTS ...)
    93##   * uncomment the "generate_dynamic_reconfigure_options" section below
    94##     and list every .cfg file to be processed
    95
    96#
    # Generate dynamic reconfigure parameters in the 'cfg' folder
    97# generate_dynamic_reconfigure_options(
    98#   cfg/DynReconf1.cfg
    99#   cfg/DynReconf2.cfg
    100# )
    101
    102#
    ##################################
    103## catkin specific configuration ##
    104## catkin 特定配置##
    105###################################
    106## The catkin_package macro generates cmake config files for your package
    107## Declare things to be passed to dependent projects
    108## INCLUDE_DIRS: uncomment this if your package  contains header files
    109## LIBRARIES: libraries you create in this project that dependent projects also need
    110## CATKIN_DEPENDS: catkin_packages dependent projects also need
    111## DEPENDS: system dependencies of this project that dependent projects also need
    112# 运行时依赖
    113catkin_package(
    114#  INCLUDE_DIRS include
    115#  LIBRARIES demo01_hello_vscode
    116#  CATKIN_DEPENDS roscpp rospy std_msgs
    117#  DEPENDS system_lib
    118)
    119
    120#
    ##########
    121## Build ##
    122###########
    123
    124#
    # Specify additional locations of header files
    125## Your package locations should be listed before other locations
    126# 添加头文件路径,当前程序包的头文件路径位于其他文件路径之前
    127include_directories(
    128# include
    129${catkin_INCLUDE_DIRS}
    130 )
    131
    132#
    # Declare a C++ library
    133# 声明 C++ 库
    134# add_library(${PROJECT_NAME}
    135# src/${PROJECT_NAME}/demo01_hello_vscode.cpp
    136# )
    137
    138#
    # Add cmake target dependencies of the library
    139## as an example, code may need to be generated before libraries
    140## either from message generation or dynamic reconfigure
    141# 添加库的 cmake 目标依赖
    142# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    143
    144#
    # Declare a C++ executable
    145## With catkin_make all packages are built within a single CMake context
    146## The recommended prefix ensures that target names across packages don't collide
    147# 声明 C++ 可执行文件
    148add_executable(Hello_VSCode src/Hello_VSCode.cpp)
    149
    150#
    # Rename C++ executable without prefix
    151## The above recommended prefix causes long target names, the following renames the
    152## target back to the shorter version for ease of user use
    153## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
    154#重命名c++可执行文件
    155# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
    156
    157#
    # Add cmake target dependencies of the executable
    158## same as for the library above
    159#添加可执行文件的 cmake 目标依赖
    160add_dependencies(Hello_VSCode   ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    161
    162#
    # Specify libraries to link a library or executable target against
    163#指定库、可执行文件的链接库
    164target_link_libraries(Hello_VSCode
    165${catkin_LIBRARIES}
    166)
    167
    168#
    ############
    169## Install ##
    170## 安装 ##
    171#############
    172
    173#
     all install targets should use catkin DESTINATION variables
    174# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
    175
    176 #
    # Mark executable scripts (Python etc.) for installation
    177 ## in contrast to setup.py, you can choose the destination
    178 #设置用于安装的可执行脚本
    179 catkin_install_python(PROGRAMS
    180 scripts/Hi.py
    181 DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    182 )
    183
    184 #
    # Mark executables for installation
    185 ## See http://docs.ros.org/melodic/api/catkin/html/howto  /format1/building_executables.html
    186 # install(TARGETS ${PROJECT_NAME}_node
    187 #   RUNTIME DESTINATION  ${CATKIN_PACKAGE_BIN_DESTINATION}
    188 # )
    189
    190 #
    # Mark libraries for installation
    191 ## See http://docs.ros.org/melodic/api/catkin/html/howto /format1/building_libraries.html
    192 # install(TARGETS ${PROJECT_NAME}
    193 #   ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    194 #   LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    195 #   RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
    196 # )
    197
    198#
    # Mark cpp header files for installation
    199# install(DIRECTORY include/${PROJECT_NAME}/
    200#   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
    201#   FILES_MATCHING PATTERN "*.h"
    202#   PATTERN ".svn" EXCLUDE
    203# )
    204
    205#
    # Mark other files for installation (e.g. launch and bag files, etc.)
    206# install(FILES
    207#   # myfile1
    208#   # myfile2
    209#   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
    210# )
    211
    212#
    ############
    213## Testing ##
    214#############
    215
    216#
    # Add gtest based cpp test target and link libraries
    217# catkin_add_gtest(${PROJECT_NAME}-test  test/test_demo01_hello_vscode.cpp)
    218# if(TARGET ${PROJECT_NAME}-test)
    219#   target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
    220# endif()
    221
    222#
    # Add folders to be run by python nosetests
    223# catkin_add_nosetests(test)

    <左右滑动以查看完整代码>

    ROS的文件系统本质上都还是操作系统文件,我们可以使用Linux命令来操作这些文件,不过,在ROS中为了更好的用户体验,ROS专门提供了一些类似于Linux的命令,这些命令较之于Linux原生命令,更为简介、高效。文件操作,无外乎就是增删改查与执行等操作,接下来,我们就从这五个维度,来介绍ROS文件系统的一些常用命令。


    1. 增


    catkin_create_pkg自定义包名依赖包===创建新的ROS功能包。


    sudo apt install xxx===安装ROS功能包。


    比如:相机功能包安装sudo apt-get install ros-noetic-usb-cam。


    2. 删


    sudo apt purge xxx====删除某个功能包。


    3. 查


    rospack list===列出所有功能包。


    rospack find 包名===查找某个功能包是否存在,如果存在返回安装路径。


    roscd 包名===进入某个功能包。


    rosls 包名===列出某个包下的文件。


    apt search xxx===所有某个功能包。


    4. 改


    rosed 包名文件名===修改功能包文件。


    需要安装vim。


    比如:rosed turtlesim Color.msg。


    5. 执行


    1. roscore


    roscore===是ROS的系统先决条件节点和程序的集合, 必须运行roscore才能使ROS节点进行通信。


    roscore将启动:


    • ros master。

    • ros参数服务器。

    • rosout日志节点。


    用法:


    roscore

    <左右滑动以查看完整代码>


    或(指定端口号)


    roscore -p xxxx

    <左右滑动以查看完整代码>

    2. rosrun


    rosrun包名可执行文件名===运行指定的ROS节点


    比如:rosrun turtlesim turtlesim_node。


    3. roslaunch


    roslaunch包名launch文件名===执行某个包下的launch文件。


    1. 计算图简介


    前面介绍的是ROS文件结构,是磁盘上ROS程序的存储结构,是静态的,而ros程序运行之后,不同的节点之间是错综复杂的,ROS中提供了一个实用的工具:rqt_graph。


    rqt_graph能够创建一个显示当前系统运行情况的动态图形。ROS分布式系统中不同进程需要进行数据交互,计算图可以以点对点的网络形式表现数据交互过程。rqt_graph是rqt程序包中的一部分。


    2. 计算图安装


    如果前期把所有的功能包(package)都已经安装完成,则直接在终端窗口中输入


    rosrun rqt_graph rqt_graph


    如果未安装则在终端(terminal)中输入


    $ sudo apt-get install ros--rqt
    $ sudo apt-get install ros--rqt-common-plugins

    <左右滑动以查看完整代码>

    请使用你的ROS版本名称(比如:kinetic、melodic、Noetic等)来替换掉

    例如当前版本是 Noetic,就在终端窗口中输入


    $ sudo apt-get install ros-noetic-rqt
    $ sudo apt-get install ros-noetic-rqt-common-plugins

    <左右滑动以查看完整代码>

    3. 计算图演示


    接下来以ROS内置的小乌龟案例来演示计算图。


    首先,按照前面所示,运行案例。


    然后,启动新终端,键入:rqt_graph或rosrun rqt_graph rqt_graph,可以看到类似下图的网络拓扑图,该图可以显示不同节点之间的关系。






    本章内容主要介绍了ROS的相关概念、设计目标、发展历程等理论知识,安装了ROS并搭建了ROS的集成开发环境,编写了第一个ROS小程序,对ROS实现架构也有了宏观的认识。ROS的大门已经敞开,接下来就要步入新的征程了。


    以上是"ROS概述与环境搭建"的全部内容,更多话题讨论、技术交流可以扫描下方二维码添加『Apollo小哥哥』为好友,进开发者交流群。






    * 以上内容为开发者原创,不代表百度官方言论,已获开发者授权。




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存